package cn.lili.modules.permission.serviceimpl;

import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.security.OperationalJudgment;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.SceneEnums;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.permission.entity.dos.Role;
import cn.lili.modules.permission.entity.dto.RoleEditDTO;
import cn.lili.modules.permission.mapper.RoleMapper;
import cn.lili.modules.permission.service.RoleMenuService;
import cn.lili.modules.permission.service.RoleService;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.mybatis.util.SceneHelp;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 角色业务层实现
 *
 * @author Chopper
 * @since 2020/11/17 3:50 下午
 */
@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {


    private final RoleMenuService roleMenuService;

    private final Cache cache;

    @Override
    public List<Role> findByDefaultRole(Boolean defaultRole) {
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("default_role", true);
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public void deleteRoles(List<String> roleIds) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.in("role_id", roleIds);
        SceneHelp.queryHandler(queryWrapper);
        //删除角色
        this.removeByIds(roleIds);
        //删除角色与菜单关联
        roleMenuService.deleteRoleMenu(roleIds);
    }

    @Override
    public List<Role> findCurrentRole() {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getScene, UserContext.getCurrentUser().getScene().name());
        queryWrapper.eq(Role::getExtendId, UserContext.getCurrentUser().getExtendId());
        return this.list(queryWrapper);
    }

    @Override
    public void saveRole(RoleEditDTO roleEditDTO) {
        Role role = roleEditDTO.getRole();
        SceneHelp.objectHandler(role);
        role.setId(SnowFlake.getIdStr());
        this.save(role);
        roleMenuService.updateRoleMenu(role.getId(), roleEditDTO.getRoleMenu());
    }

    @Override
    public Page pageRole(PageVO pageVo, Role role) {
        QueryWrapper queryWrapper = PageUtil.initWrapper(role);
        SceneHelp.queryHandler(queryWrapper, true);
        return this.page(PageUtil.initPage(pageVo), queryWrapper);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRoleById(RoleEditDTO roleEditDTO) {
        OperationalJudgment.judgment(this.getById(roleEditDTO.getRole().getId()));
        Role role = roleEditDTO.getRole();
        SceneHelp.objectHandler(role);
        roleMenuService.updateRoleMenu(role.getId(), roleEditDTO.getRoleMenu());
        this.saveOrUpdate(role);
        cache.vagueDel(CachePrefix.USER_MENU.getVaguePrefix(SceneEnums.valueOf(role.getScene())));
        cache.vagueDel(CachePrefix.PERMISSION_LIST.getVaguePrefix(SceneEnums.valueOf(role.getScene())));
    }
}
